package ontology;

import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.Serializable;

/**
 * <p>
 * <B>Title:</b> Fire Evacuation
 * </p>
 * *
 * <p>
 * This class keeps all the information about a cell in the map. *
 * 
 * 
 * @author Carolina Arce & Caterina Bruno
 */
public class Cell implements Serializable, MouseListener {

	static public int FREE = 1;
	static public int FIRE = 2;
	static public int DOOR = 3;
	static public int OBJECT = 4;
	static public int STAIRS = 5;
	static public int SMOKE = 6;
	public int nrows;
	public int ncols;
	public int nfloor;
	private int type;

	private boolean haveAgent = false;
	private InfoAgent agent = null;

	// only for fire
	private double fireIntensityUnits = 0;

	private boolean discovered = true;
	private static final long serialVersionUID = 1L;

	public Cell(int type) {
		this.type = type;
		this.discovered = true;
	}

	/**************************************************************************/

	public int getCellType() {
		return this.type;
	}

	public void setCellType(int newType) throws Exception {
		if ((newType != FREE) && (newType != FIRE) && (newType != DOOR)
				&& (newType != OBJECT) && (newType != STAIRS)
				&& (newType != SMOKE))
			throw new Exception("Unknown type");
		this.type = newType;
	}

	static public String getCellType(int tipus) {
		if (tipus == FREE)
			return "B";
		if (tipus == FIRE)
			return "F";
		if (tipus == DOOR)
			return "D";
		if (tipus == STAIRS)
			return "S";
		if (tipus == OBJECT)
			return "O";
		if (tipus == SMOKE)
			return "K";
		return "";
	}

	/**************************************************************************/

	/**************************************************************************/

	public double getFireIntensityUnits() {
		return fireIntensityUnits;
	}

	public void setFireIntensityUnits(double fireIntensityUnits) {
		this.fireIntensityUnits = fireIntensityUnits;
	}

	/**************************************************************************/

	public boolean isThereAnAgent() {
		return (this.haveAgent);
	}

	public void addAgent(InfoAgent newAgent) throws Exception {
		System.out.println("Adding an agent in pos" + this.getColumn()
				+ this.getRow() + this.getFloor());

		if ((this.getCellType() == OBJECT) || (this.getCellType() == FIRE)) {

			System.out.println("in adding agent cell is full");
			throw new Exception("Wrong operation");
		}
		if ((this.getCellType() == FREE) && (this.isThereAnAgent()))
			throw new Exception("Full cell");

		if ((this.getCellType() == DOOR) && (this.isThereAnAgent()))
			throw new Exception("Full cell");

		if ((this.getCellType() == STAIRS) && (this.isThereAnAgent()))
			throw new Exception("Full cell");
		if ((this.getCellType() == SMOKE) && (this.isThereAnAgent()))
			throw new Exception("Full cell");

		if (this.isAgent(newAgent))
			throw new Exception("Repeated InfoAgent");

		// if everything is OK, we add the new agent to the cell
		this.agent = newAgent;
		this.haveAgent = true;
	}

	private boolean isAgent(InfoAgent newAgent) {
		if (newAgent == null)
			return false;
		else {
			if (this.agent != null)
				return this.agent.equals(newAgent);
			else
				return false;
		}
	}

	public void removeAgent(InfoAgent oldInfoAgent) {
		try {
			if ((this.getCellType() == OBJECT) || (this.getCellType() == FIRE)) {
				System.out.println("in removing agent cell is full");
				System.out.println("Wrong operation");
			}
			if (this.agent == null)
				System.out.println("No agents in this cell");
			if (!this.isAgent(oldInfoAgent))
				System.out.println("InfoAgent not here");
			// if everything is OK, we remove the agent from the cell
			this.agent = null;
			this.haveAgent = false;
		} catch (Exception e) {
			e.toString();
			System.out.println("exception while removing agent" + oldInfoAgent);
		}
	}

	public InfoAgent getAgent() {
		return this.agent;
	}

	/**************************************************************************/
	private int row = -1;
	private int column = -1;
	private int floor = -1;

	public int getFloor() {
		return floor;
	}

	public void setFloor(int floor) {
		this.floor = floor;
	}

	public void setRow(int i) {
		this.row = i;
	}

	public int getRow() {
		return this.row;
	}

	public void setColumn(int i) {
		this.column = i;
	}

	public int getColumn() {
		return this.column;
	}

	public int getNrows() {
		return nrows;
	}

	public int getNfloor() {
		return nfloor;
	}

	public void setNfloor(int nfloor) {
		this.nfloor = nfloor;
	}

	public void setNrows(int nrows) {
		this.nrows = nrows;
	}

	public int getNcols() {
		return ncols;
	}

	public void setNcols(int ncols) {
		this.ncols = ncols;
	}

	public boolean isDiscovered() {
		return discovered;
	}

	public void setDiscovered(boolean discovered) {
		this.discovered = discovered;
	}

	/**************************************************************************/

	public String toString() {
		String str = "";
		try {
			str = "(cell-type " + this.getCellType(this.getCellType()) + " "
					+ "(row " + this.getRow() + ")" + "(column "
					+ this.getColumn() + ") (floor" + this.getFloor() + ")";
			if (!discovered)
				str = str + "???";
			if (this.type == this.FREE) {
				if (this.isThereAnAgent())
					str = str + "(there-is-an-agent ";
				else
					str = str + "(empty ";
				if (agent != null)
					str = str + this.agent.toString();
				str = str + ")";
			}
			if (this.type == this.FIRE) {
				str = str + "(fire at pos " + this.getRow() + "-"
						+ this.getColumn() + "-" + this.getFloor() + ")";
			}
			if (this.type == this.DOOR) {
				str = str + "(door at " + this.getRow() + "-"
						+ this.getColumn() + "-" + this.getFloor() + ")";
			}
			if (this.type == this.OBJECT) {
				str = str + "(obstacule " + this.getRow() + "-"
						+ this.getColumn() + "-" + this.getFloor() + ")";
			}
			if (this.type == this.STAIRS) {
				str = str + "(stairs " + this.getRow() + "-" + this.getColumn()
						+ "-" + this.getFloor() + ")";
			}
			str = str + ")";
		} catch (Exception e) {
			e.printStackTrace();
		}
		return str;
	}

	public String getFireIntensityString() throws Exception {
		if (this.getCellType() != Cell.FIRE)
			throw new Exception("Wrong operation");
		if (fireIntensityUnits == 0)
			return "";
		else {
			return "" + Math.round(fireIntensityUnits);
		}
	}

	public boolean blockingAgent() throws Exception {
		if (this.haveAgent
				&& !(this.getAgent().panic >= 80 || this.getAgent().injured || this
						.getAgent().died == true))
			return false;
		else
			return true;
	}

	public boolean isFree() throws Exception {
		if (this.haveAgent
				&& (this.getAgent().panic >= 80 || this.getAgent().injured || this
						.getAgent().died == true))
			return false;

		if ((this.getCellType() == OBJECT) || (this.getCellType() == FIRE)) {

			return false;
		}
		return true;
	}

	@Override
	public void mouseClicked(MouseEvent arg0) {
		// TODO Auto-generated method stub
		// if (this.isThereAnAgent())
		System.out.println("Mouse event");

	}

	@Override
	public void mouseEntered(MouseEvent arg0) {
		// TODO Auto-generated method stub
		System.out.println("Mouse event");

	}

	@Override
	public void mouseExited(MouseEvent arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void mousePressed(MouseEvent arg0) {
		// TODO Auto-generated method stub
		System.out.println("Mouse event");

	}

	@Override
	public void mouseReleased(MouseEvent arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public boolean equals(Object obj) {
		// TODO Auto-generated method stub
		return super.equals(obj);
	}
} // endof class Cell
